package com.shievy.anweb.webview.main

import com.google.gson.Gson
import com.google.gson.GsonBuilder
import com.shievy.anweb.base.uitl.LogUtil
import com.shievy.anweb.webview.IJSToNativeAidlInterface
import com.shievy.anweb.webview.INativeToJSAidlInterface
import com.shievy.anweb.webview.api.WebTelecomApiService
import com.shievy.anweb.webview.entry.JsParams
import com.shievy.anweb.webview.entry.WebHandler
import java.util.ServiceLoader

/**
 * 用于跨进程通讯的Binder
 *
 * */
class WebTelecomServiceManager private constructor() : IJSToNativeAidlInterface.Stub() {
    private val gson: Gson by lazy { GsonBuilder().create() }
    private val webTelecomServices: MutableMap<String, WebTelecomApiService> by lazy { mutableMapOf() }

    init {
        /**
         * 使用 @AutoService 自动加载所有的 WebTelecomApiService 对应的原生方法
         * */
        ServiceLoader.load(WebTelecomApiService::class.java).iterator().let {
            while (it.hasNext()) {
                it.next()?.let { web ->
                    webTelecomServices.put(web.telecomID(), web)
                }
            }
        }

        LogUtil.i("webTelecomServices == > ", webTelecomServices)
    }

    companion object {
        private var instance: WebTelecomServiceManager? = null
        fun getWebTelecomService(): WebTelecomServiceManager? {
            if (instance == null) {
                synchronized(WebTelecomServiceManager::class) {
                    instance = WebTelecomServiceManager()
                    return instance
                }
            } else {
                return instance
            }

        }
    }


    /**
     * 来自JS 的消息处理
     * */
    override fun callNativeMain(telecomID: String?, params: String?, jsMethodID: String?) {
        telecomID?.let {
            webTelecomServices[telecomID]?.let {
                it.doNext(JsParams(telecomID, jsMethodID, gson.fromJson(params, Map::class.java)))
            }
        }

    }

    /**
     * 调用Web JS 函数
     * */
    override fun callNativeBackToWebJs(
        telecomID: String?, params: String?, jsMethodID: String?,
        nativeToJs: INativeToJSAidlInterface?
    ) {
        telecomID?.let {
            webTelecomServices[telecomID]?.let {
                it.doNext(
                    JsParams(telecomID, jsMethodID, gson.fromJson(params, Map::class.java)),
                    object : WebHandler {
                        override fun commit(param: String?) {
                            nativeToJs?.let { stub ->
                                stub.callWebJs(telecomID, param, jsMethodID)
                            }
                        }
                    })
            }
        }
    }
}